
#include "app.h"

static GPIO_AL0_Status  g_GPIO_AL0_Status = GPIO_AL0_STATUS_PENDING;
static GPIO_PB1_Status g_GPIO_PB1_Status = GPIO_PB1_IDLE;


void GPIO_Interface_Init(void)
{
    GPIO_InitTypeDef  GPIO_InitStruct;
    GPIO_PinState pinStatus;

    __HAL_RCC_GPIOA_CLK_ENABLE();

    /* 配置GPIO_SCL GPIO_AL0 DELINK为输入引脚*/
    GPIO_InitStruct.Pin       = GPIO_SCL_PA2_PIN | DELINK_PA9_PIN;
    GPIO_InitStruct.Mode      = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull      = GPIO_NOPULL;
    GPIO_InitStruct.Drive     = GPIO_DRIVE_LEVEL3;
    GPIO_InitStruct.Alternate = GPIO_FUNCTION_0;

    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /* 配置GPIO_AL0为输入中断引脚，上升沿表示进入指纹事件*/
    GPIO_InitStruct.Pin       = GPIO_AL0_PA4_PIN;
    GPIO_InitStruct.Mode      = GPIO_MODE_IT_RISING_FALLING;
    GPIO_InitStruct.Pull      = GPIO_NOPULL;
    GPIO_InitStruct.Drive     = GPIO_DRIVE_LEVEL3;
    GPIO_InitStruct.Alternate = GPIO_FUNCTION_0;

    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
	HAL_EXTI_ClearPending(GPIO_AL0_PA4_PIN);
    NVIC_ClearPendingIRQ(EXTI4_IRQn);
    NVIC_SetPriority(EXTI4_IRQn, 1u); //中断优先级设置相对高一点，本次设置为1
    NVIC_EnableIRQ(EXTI4_IRQn);


    __HAL_RCC_GPIOA_CLK_ENABLE();

    //GPIO 管脚配置为输入中断脚, 下降沿电平触发
    GPIO_InitStruct.Pin       = GPIO_PB1_PIN;
    GPIO_InitStruct.Mode      = GPIO_MODE_IT_FALLING;
    GPIO_InitStruct.Pull      = GPIO_PULLUP;//由于awp1921是开漏输出，需要上拉
    GPIO_InitStruct.Drive     = GPIO_DRIVE_LEVEL3;
    GPIO_InitStruct.Alternate = GPIO_FUNCTION_0;

    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

	HAL_EXTI_ClearPending(GPIO_PB1_PIN);
    NVIC_ClearPendingIRQ(EXTI1_IRQn);
    NVIC_SetPriority(EXTI1_IRQn, 2u); //中断优先级设置相对高一点，本次设置为2
    NVIC_EnableIRQ(EXTI1_IRQn);

    /* 确认 上电初始化时GPIO_AL0  电平状态 */
    pinStatus = HAL_GPIO_ReadPin(GPIOA, GPIO_AL0_PA4_PIN);

    if (pinStatus == GPIO_PIN_LOW) {
        g_GPIO_AL0_Status = EC_CONTROL_STATUS_BOTTON;
    } else  {
        g_GPIO_AL0_Status = ELAN_FP_STATUS_COMPARISON_START;
    }


    /* 确认 上电初始化时GPIO_AL0  电平状态 */
    pinStatus = HAL_GPIO_ReadPin(GPIOB, GPIO_PB1_PIN);

    if (pinStatus == GPIO_PIN_LOW) {
        g_GPIO_PB1_Status = GPIO_PB1_PRESS_RELEASS;
    } else {
        g_GPIO_PB1_Status = GPIO_PB1_IDLE;
    }

    g_GPIO_PB1_Status = GPIO_PB1_IDLE;

}

/* GPIO PB1中断回调函数 */
void HAL_EXTI_LineCallback(uint32_t Line)
{
    GPIO_PinState pinStatus;
    uint16_t regVal = 0u;
	if (Line == GPIO_PB1_PIN)
	{
        // 由于 awp1921 中断脚读状态寄存器可以由低电平自动变高电平,用于恢复
        regVal = AWP1921_Read_Status();
        g_GPIO_PB1_Status = GPIO_PB1_PRESS_RELEASS;
	} else if (Line ==  GPIO_AL0_PA4_PIN) {
        pinStatus = HAL_GPIO_ReadPin(GPIOA, GPIO_AL0_PA4_PIN);
        if (pinStatus == GPIO_PIN_HIGH) {
            g_GPIO_AL0_Status = ELAN_FP_STATUS_COMPARISON_START;

            AWP1921_Sense_EnablePlay_Or_Stop(AWP1921_ENABLE_SENSE_PLAY);
        } else {
            g_GPIO_AL0_Status = ELAN_FP_STATUS_PENDING_START;
        }
    }
}

/* 计算时间上的间隔 */
uint32_t HAL_Delay_Interval_MS(uint32_t old_ms, uint32_t new_ms)
{
    uint32_t ms_increment = 0;

    if(old_ms <= new_ms)
    {
        ms_increment = new_ms - old_ms;
    }
    else
    {
        ms_increment = 0xffffffff - old_ms + new_ms;
    }

    return ms_increment;
}

void APP_Deal_GPIO_AL0_Status(void)
{
    uint32_t current_tick = 0u;
    GPIO_PinState pinStatus;
    static uint8_t elanFPFailTimes = 0x00;  //指纹登录失败次数

    switch(g_GPIO_AL0_Status) {
        case EC_CONTROL_STATUS_BOTTON:
            // botton事件 取消sense振动功能
            if (g_GPIO_PB1_Status == GPIO_PB1_PRESS_RELEASS) {//存在按压
                AWP1921_Sense_EnablePlay_Or_Stop(AWP1921_SENSE_STOP_PLAY);
                g_GPIO_PB1_Status = GPIO_PB1_IDLE;
                AWP1921_SRAM_Play_Or_Stop(AWP1921_SRAM_MIDIUM_PLAY);//slice0播放振动波形
                printf("AWP1921_SRAM_Play_Or_Stop MIDIUM \r\n");
            }

            break;
        case ELAN_FP_STATUS_COMPARISON_START:
            /*有按压就会振动 slice1波形，需要使能sense振动 */
            if (g_GPIO_PB1_Status == GPIO_PB1_PRESS_RELEASS) {
                AWP1921_Sense_EnablePlay_Or_Stop(AWP1921_ENABLE_SENSE_PLAY);
                g_GPIO_PB1_Status = GPIO_PB1_IDLE;
            }
            break;
        case ELAN_FP_STATUS_COMPARISON_SUCCESS:

            if (g_GPIO_PB1_Status == GPIO_PB1_PRESS_RELEASS) { //存在按压
                // 取消sense振动功能, 播放长波
                g_GPIO_PB1_Status = GPIO_PB1_IDLE;
            }
            g_GPIO_AL0_Status = EC_CONTROL_STATUS_BOTTON;

            // 取消sense振动功能, 播放长波
            printf("elanFPFailTimes :%d \r\n", elanFPFailTimes);
            if (elanFPFailTimes < 3) {
	            AWP1921_Sense_EnablePlay_Or_Stop(AWP1921_SENSE_STOP_PLAY);
	            AWP1921_SRAM_Play_Or_Stop(AWP1921_SRAM_SHORT_PLAY);//slice0播放振动波形
				elanFPFailTimes = 0;
            }
			elanFPFailTimes = 0;
            HAL_EXTI_ClearPending(GPIO_AL0_PA4_PIN);
            NVIC_ClearPendingIRQ(EXTI4_IRQn);
            NVIC_SetPriority(EXTI4_IRQn, 1u); //中断优先级设置相对高一点，本次设置为1
            NVIC_EnableIRQ(EXTI4_IRQn);

            break;
        case ELAN_FP_STATUS_COMPARISON_FAIL:
            elanFPFailTimes++;
            if (g_GPIO_PB1_Status == GPIO_PB1_PRESS_RELEASS) { //存在按压
                g_GPIO_PB1_Status = GPIO_PB1_IDLE;

            }
            // 取消sense振动功能, 播放长波
            AWP1921_Sense_EnablePlay_Or_Stop(AWP1921_SENSE_STOP_PLAY);
            AWP1921_SRAM_Play_Or_Stop(AWP1921_SRAM_LONG_PLAY);//slice0播放振动波形
            printf("ELAN_FP_STATUS_COMPARISON_FAIL \r\n");

            g_GPIO_AL0_Status = EC_CONTROL_STATUS_BOTTON;
            HAL_EXTI_ClearPending(GPIO_AL0_PA4_PIN);
            NVIC_ClearPendingIRQ(EXTI4_IRQn);
            NVIC_SetPriority(EXTI4_IRQn, 1u); //中断优先级设置相对高一点，本次设置为1
            NVIC_EnableIRQ(EXTI4_IRQn);
            break;
        case ELAN_FP_STATUS_PENDING:
#if 0
            while (HAL_Delay_Interval_MS(current_tick, HAL_GetTick()) < 55) {
				printf("current_tick = 0x%04x \r\n", current_tick);
				printf("HAL_GetTick = 0x%04x \r\n",HAL_GetTick());
                pinStatus = HAL_GPIO_ReadPin(GPIOA, GPIO_AL0_PA4_PIN);
                if (pinStatus == GPIO_PIN_HIGH) {
                    g_GPIO_AL0_Status = ELAN_FP_STATUS_COMPARISON_FAIL;
                    printf("entre ELAN_FP_STATUS_COMPARISON_FAIL \r\n");
                    break;
                }
            }
#endif

			HAL_Delay(50);
			
			pinStatus = HAL_GPIO_ReadPin(GPIOA, GPIO_AL0_PA4_PIN);
			if (pinStatus == GPIO_PIN_HIGH) {
				g_GPIO_AL0_Status = ELAN_FP_STATUS_COMPARISON_FAIL;
				printf("entre ELAN_FP_STATUS_COMPARISON_FAIL \r\n");
				break;
			} else {
				printf("enter ELAN_FP_STATUS_COMPARISON_SUCCESS \r\n");
				g_GPIO_AL0_Status = ELAN_FP_STATUS_COMPARISON_SUCCESS;
			}
			
            if (g_GPIO_PB1_Status == GPIO_PB1_PRESS_RELEASS) { //存在按压
                g_GPIO_PB1_Status = GPIO_PB1_IDLE;
            }
            break;

        case ELAN_FP_STATUS_PENDING_START:
            // PENDDING状态需要关闭中断，采用轮询的方式来查询是进入指纹成功还是失败的状态
            printf("ELAN_FP_STATUS_PENDING_START \r\n");
            NVIC_ClearPendingIRQ(EXTI4_IRQn);
            NVIC_EnableIRQ(EXTI4_IRQn);
            g_GPIO_AL0_Status = ELAN_FP_STATUS_PENDING;
            current_tick = HAL_GetTick();
            if (g_GPIO_PB1_Status == GPIO_PB1_PRESS_RELEASS) { //存在按压
                g_GPIO_PB1_Status = GPIO_PB1_IDLE;
            }
			break;

        case GPIO_AL0_STATUS_PENDING:  //这个分支是为了消除告警，而且正常流程不会到这里
            pinStatus = HAL_GPIO_ReadPin(GPIOA, GPIO_AL0_PA4_PIN);
            if (pinStatus == GPIO_PIN_HIGH) {
                g_GPIO_AL0_Status = ELAN_FP_STATUS_PENDING;

            } else {
                g_GPIO_AL0_Status = EC_CONTROL_STATUS_BOTTON;
            }
            break;
        defualt:
             break;
    }
}

void APP_Loop(void)
{
    APP_Deal_GPIO_AL0_Status();
#if 0

    GPIO_PinState status;

    uint16_t awp_status = 0x0000;
    status = HAL_GPIO_ReadPin(GPIOA, GPIO_SCL_PA2_PIN);

    if (status == GPIO_PIN_RESET) {
        printf("GPIO_SCL low \r\n");
    } else {
        printf("GPIO_SCL high \r\n");
    }
    status = HAL_GPIO_ReadPin(GPIOA, GPIO_AL0_PA4_PIN);

    if (status == GPIO_PIN_RESET) {
        printf("GPIO_AL0 low \r\n");
    } else {
        printf("GPIO_AL0 high \r\n");
    }


    status = HAL_GPIO_ReadPin(GPIOA, DELINK_PA9_PIN);

    if (status == GPIO_PIN_RESET) {
        printf("DELINK low \r\n");
    } else {
        printf("DELINK high \r\n");
    }

    status = HAL_GPIO_ReadPin(GPIOB, GPIO_PB1_PIN);

    if (status == GPIO_PIN_RESET) {
        printf("GPIO low \r\n");
    } else {
        printf("GPIO high \r\n");
    }


    if (playflag == 1) {
        awp_status = AWP1921_Read_Status();
    }



    static uint8_t playflag = 0x00;

    if (playflag == 0x01) {
        AWP1921_I2C_Write_REG(AWP1921_REG_ADDR_06, 0x0004); //play 播放
    }

    if (playflag == 0x02) {
        AWP1921_I2C_Write_REG(AWP1921_REG_ADDR_06, 0x0001); //ADC开启采样
    }

    uint16_t adcDate = 0x0000;
    uint16_t status = 0x0000;
    adcDate = AWP1921_Read_ADC_Date();
    printf("%s:%d: adcDate:0x%04x \r\n",__FILE__, __LINE__,adcDate);
    status = AWP1921_Read_Status();
    printf("%s:%d: status:0x%04x \r\n",__FILE__, __LINE__,status);
#endif
}



